//Arduino Klok
//Source: https://github.com/alatas/tm1638-clock/blob/master/tm1638_clock/tm1638_clock.ino
//Source: https://www.edutechsoft.nl/Interface%20en%20Badge/

/* 
Voor Arduino Nano met TM1638 module
edutechsoft.nl
28 januari 2024
TM1638 v1.1 en v1.3
Een klok zonder klokchip
Handmatig tijd invoeren met de knoppen op de TM1638

Knoppen...
1 = uur + 1
2 = uur - 1
3 = minuten + 1
4 = minuten - 1
5 = seconden op 0
6 = display on/off
7 = helderheid - 1
8 = helderheid + 1
*/


#include <InvertedTM1638.h>
#include <TM1638.h>
#include <TM1640.h>
#include <TM16XX.h>

// Bepaal op welke pinnen STB, CLK en DIO aangesloten zijn.

// Voor Arduino Nano op universeel PCB
TM1638  module(2, 3, 4);

// Voor Arduino Nano Badge
//TM1638 tm module(4, 3, 2);

unsigned long waitcheckTime=0;
unsigned long waitcheckButtons=0;

unsigned long intervalcheckTime=1000;
unsigned long intervalcheckButtons=100;

unsigned long gapSecond = 0;
boolean dots = 0;

boolean moduleOff=0;

int Helderheid = 2, HelderheidOud = 2;

void setup(){
  module.setupDisplay(true,Helderheid);
  waitcheckTime = intervalcheckTime;
  waitcheckButtons = intervalcheckButtons;
}

void loop(){
  checkTime();
  checkButtons();
}

void checkTime(){
  if (millis() >= waitcheckTime) {
    dots = !dots;
    drawToModule();
    waitcheckTime += intervalcheckTime;
  }
}

void checkButtons(){
  if (millis() >= waitcheckButtons) {
    module.setLEDs(0);
    byte buttons=module.getButtons();
    if(buttons>0){
      for (byte i=0;i<8;i++){
        if ((buttons & 1<<i) != 0) {
          buttonEvent(i);
          waitcheckButtons +=intervalcheckButtons;
          drawToModule();
        }
      }
    }
    waitcheckButtons +=intervalcheckButtons;
  }
}

void drawToModule(){
  if (!moduleOff){
    unsigned long elapSecond = round(millis() / 1000);
    unsigned long totalSecond = gapSecond + elapSecond;
    //tm.clearDisplay();
    module.setDisplayToString(formatTime(totalSecond));
  }
}

void buttonEvent(byte inp){
  module.setLED(1,inp);
  //tm.setLED((inp % 2 ) + 1,inp); For V1.3 only
  switch (inp){
  case 0:
    if (hour(gapSecond) != 23)    {  
      gapSecond += 3600    ; 
    }
    else      {
      gapSecond -= 82800;
    }
    break;
  case 1:
    if (hour(gapSecond) != 0){
      gapSecond -= 3600;
    }
    else{
      gapSecond += 82800;
    }
    break;
  case 2:
    if (minute(gapSecond) != 59){
      gapSecond += 60;
    }
    else{
      gapSecond -= 3540;
    }
    break;
  case 3:
    if (minute(gapSecond) != 0){
      gapSecond -= 60;
    }
    else{
      gapSecond += 3540;
    }
    break;
  case 4:
    gapSecond -= second(gapSecond + round(millis() / 1000)); 
    break;
  case 5:
    moduleOff = !moduleOff;
    if (moduleOff) module.clearDisplay();
    break;
  case 6:
    Helderheid--;
    if (Helderheid < 0){
      Helderheid = 3;
    }
    if (HelderheidOud != Helderheid){
      module.setupDisplay(true,Helderheid);
      module.setLED(1,Helderheid);
      HelderheidOud = Helderheid;
    }    
    break;
  case 7:
    Helderheid++;
    if (Helderheid > 3){
      Helderheid = 0;
    }
    if (HelderheidOud != Helderheid){
      module.setupDisplay(true,Helderheid);
      module.setLED(1,Helderheid);
      HelderheidOud = Helderheid;
    }
    break;
  }
}

String formatTime(unsigned long inp){
  return hourStr(inp) + "-" + minuteStr(inp) + "-" + secondStr(inp);
}

String formatNumber(String inp){
  if (inp.length()==1) {
    return "0" + inp;
  }
  else{
    return inp;
  }
}

String hourStr(unsigned long inp){
  return  formatNumber(String(hour(inp)));
}

String minuteStr(unsigned long inp){
  return  formatNumber(String(minute(inp)));
}

String secondStr(unsigned long inp){
  return  formatNumber(String(second(inp)));
}

byte hour(unsigned long inp){
  return  byte((inp/3600) % 24);
}

byte minute(unsigned long inp){
  return  byte((inp/60) % 60);
}

byte second(unsigned long inp){
  return  byte(inp % 60);
}